home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1994 November: Tool Chest / Dev.CD Nov 94.toast / Tool Chest / Development Tools & Languages / • Other Platforms / PCCTS / h / ATokenBuffer.C < prev    next >
Encoding:
C/C++ Source or Header  |  1994-09-14  |  6.0 KB  |  196 lines  |  [TEXT/MPS ]

  1. /* ANTLRTokenBuffer.C
  2.  *
  3.  * SOFTWARE RIGHTS
  4.  *
  5.  * We reserve no LEGAL rights to the Purdue Compiler Construction Tool
  6.  * Set (PCCTS) -- PCCTS is in the public domain.  An individual or
  7.  * company may do whatever they wish with source code distributed with
  8.  * PCCTS or the code generated by PCCTS, including the incorporation of
  9.  * PCCTS, or its output, into commerical software.
  10.  * 
  11.  * We encourage users to develop software with PCCTS.  However, we do ask
  12.  * that credit is given to us for developing PCCTS.  By "credit",
  13.  * we mean that if you incorporate our source code into one of your
  14.  * programs (commercial product, research project, or otherwise) that you
  15.  * acknowledge this fact somewhere in the documentation, research report,
  16.  * etc...  If you like PCCTS and have developed a nice tool with the
  17.  * output, please mention that you developed it using PCCTS.  In
  18.  * addition, we ask that this header remain intact in our source code.
  19.  * As long as these guidelines are kept, we expect to continue enhancing
  20.  * this system and expect to make other tools available as they are
  21.  * completed.
  22.  *
  23.  * ANTLR 1.23
  24.  * Terence Parr
  25.  * Parr Research Corporation
  26.  * with Purdue University and AHPCRC, University of Minnesota
  27.  * 1989-1994
  28.  */
  29.  
  30. typedef int TokenType;    // fool AToken.h into compiling
  31. #include "config.h"
  32. #include ATOKENBUFFER_H
  33.  
  34. /* Some C++ compilers cannot handle static variables in inline functions.
  35.  * THEREFORE, I have to make all of the static variables used by functions
  36.  * in the ANTLRToken class hierarchy into member variables.  Because
  37.  * there is no AToken.C file at the moment, I'm just going to put
  38.  * the static member variable defs here.  It's hideous: so sue me.
  39.  */
  40. ANTLRTokenBase ANTLRTokenBase::t;
  41. ANTLRCommonToken ANTLRCommonToken::t;
  42.  
  43.  
  44. ANTLRTokenBuffer::
  45. ANTLRTokenBuffer(ANTLRTokenStream *input, int k, int cs)
  46. {
  47.     this->input = input;
  48.     this->k = k;
  49.     buffer_size = chunk_size = cs;
  50.     buffer = (ANTLRAbstractToken **)calloc(chunk_size,
  51.                                              sizeof(ANTLRAbstractToken *));
  52.     if ( buffer == NULL ) {
  53.         panic("cannot alloc token buffer");
  54.     }
  55.     tp = &buffer[0];
  56.     last = tp-1;
  57.     next = &buffer[0];
  58.     num_markers = 0;
  59.     end_of_buffer = &buffer[buffer_size-1];
  60. }
  61.  
  62. ANTLRTokenBuffer::
  63. ~ANTLRTokenBuffer()
  64. {
  65.     if ( buffer!=NULL ) free((char *)buffer);
  66. }
  67.  
  68. //#include <stdio.h>
  69.  
  70. ANTLRAbstractToken *ANTLRTokenBuffer::
  71. getToken()
  72. {
  73.     if ( tp <= last )            // is there any buffered lookahead still to be read?
  74.     {
  75.         return *tp++;            // read buffered lookahead
  76.     }
  77.     // out of buffered lookahead, get some more "real" input from getANTLRToken()
  78.     if ( next > end_of_buffer )    // buffer overflow?
  79.     {
  80. //        fprintf(stderr, "getToken: next > end_of_buffer (size is %d)\n", buffer_size);
  81.         makeRoom();
  82.     }
  83.     *next = getANTLRToken();
  84.     last = next;
  85.     next++;
  86.     tp = last;
  87.     return *tp++;
  88. }
  89.  
  90. void ANTLRTokenBuffer::
  91. rewind(int pos)
  92. {
  93.     tp = &buffer[pos];
  94.     num_markers--;
  95. }
  96.  
  97. /*
  98.  * This function is used to specify that the token pointers read
  99.  * by the ANTLRTokenBuffer should be buffered up (to be reused later).
  100.  */
  101. int ANTLRTokenBuffer::
  102. mark()
  103. {
  104.     num_markers++;
  105.     return tp - buffer;
  106. }
  107.  
  108. /*
  109.  * returns the token pointer n positions ahead.
  110.  * This implies that bufferedToken(1) gets the NEXT symbol of lookahead.
  111.  * This is used in conjunction with the ANTLRParser lookahead buffer.
  112.  *
  113.  * No markers are set or anything.  A bunch of input is buffered--that's all.
  114.  * The tp pointer is left alone as the lookahead has not been advanced
  115.  * with getToken().  The next call to getToken() will find a token
  116.  * in the buffer and won't have to call getANTLRToken().
  117.  */
  118. ANTLRAbstractToken *ANTLRTokenBuffer::
  119. bufferedToken(int n)
  120. {
  121.     int how_many_more_i_need = n-(last-tp)-1;
  122.     // Make sure that at least n tokens are available in the buffer
  123. //    fprintf(stderr, "bufferedToken(%d)\n", n);
  124.     for (int i=1; i<=how_many_more_i_need; i++)
  125.     {
  126.         if ( next > end_of_buffer )    // buffer overflow?
  127.         {
  128.             extendBuffer();
  129.         }
  130.         *next = getANTLRToken();
  131.         last = next;
  132.         next++;
  133.     }
  134.     return tp[n - 1];
  135. }
  136.  
  137. /* If no markers are set, the none of the input needs to be saved (except
  138.  * for the lookahead Token pointers).  We save only k-1 token pointers as
  139.  * we are guaranteed to do a getANTLRToken() right after this because otherwise
  140.  * we wouldn't have needed to extend the buffer.
  141.  *
  142.  * If there are markers in the buffer, we need to save things and so
  143.  * extendBuffer() is called.
  144.  */
  145. void ANTLRTokenBuffer::
  146. makeRoom()
  147. {
  148. //    fprintf(stderr, "in makeRoom.................\n");
  149.     if ( num_markers == 0 )
  150.     {
  151. //        fprintf(stderr, "num_markers==0; moving lookahead and resetting next\n");
  152. //        fprintf(stderr, "before: tp=%d, last=%d, next=%d\n", tp-buffer, last-buffer, next-buffer);
  153.         // reset the buffer to initial conditions, but move k-1 lookahead symbols
  154.         // to the beginning of buffer and put new input symbol at k
  155.         ANTLRAbstractToken **p = buffer, **q = end_of_buffer-(k-1);
  156. //        fprintf(stderr, "lookahead buffer = [");
  157.         for (int i=1; i<=k; i++)
  158.         {
  159.             *p++ = *q++;
  160. //            fprintf(stderr, " '%s'", ((ANTLRCommonToken *)buffer[i-1])->getText());
  161.         }
  162. //        fprintf(stderr, "]\n");
  163.         next = &buffer[k];
  164.         tp = &buffer[k];    // tp points to what will be filled in next
  165.         last = tp-1;
  166. //        fprintf(stderr, "after: tp=%d, last=%d, next=%d\n", tp-buffer, last-buffer, next-buffer);
  167.     }
  168.     else {
  169.         extendBuffer();
  170.     }
  171. }
  172.  
  173. /* This function extends 'buffer' by chunk_size and returns with all
  174.  * pointers at the same relative positions in the buffer (the buffer base
  175.  * address could have changed in realloc()) except that 'next' comes
  176.  * back set to where the next token should be stored.  All other pointers
  177.  * are untouched.
  178.  */
  179. void
  180. ANTLRTokenBuffer::
  181. extendBuffer()
  182. {
  183.     int save_last = last-buffer, save_tp = tp-buffer, save_next = next-buffer;
  184. //    fprintf(stderr, "extending physical buffer\n");
  185.     buffer_size += chunk_size;
  186.     buffer = (ANTLRAbstractToken **)
  187.              realloc((char *)buffer, buffer_size * sizeof(ANTLRAbstractToken *));
  188.     if ( buffer == NULL ) {
  189.         panic("cannot alloc token buffer");
  190.     }
  191.     tp = buffer + save_tp;    // put the pointers back to same relative position
  192.     last = buffer + save_last;
  193.     next = buffer + save_next;
  194.     end_of_buffer = &buffer[buffer_size-1];
  195. }
  196.